home *** CD-ROM | disk | FTP | other *** search
- /* Support routines for Eclectus integration utilities.
- Copyright (C) 1992-1996 Eclectus (D. John Anderson, Alan B. Harper).
-
- This file is part of the Eclectus integration utilities.
-
- Eclectus integration utilities are free software; you can redistribute
- it and/or modify it under the terms of the GNU General Public License
- as published by the Free Software Foundation; either version 1, or
- (at your option) any later version.
-
- Eclectus integration utilities is distributed in the hope that it
- will be useful, but WITHOUT ANY WARRANTY; without even the implied
- warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
- See the GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with the Eclectus integration utilities; see the file COPYING.
- If not, write to the Free Software Foundation, 675 Mass Ave, Cambridge,
- MA 02139, USA. */
-
- #include "diff.h"
- #include <stdlib.h>
- #include <string.h>
- #ifdef DF_MACHINE_MACINTOSH
- #include <Types.h>
- #endif
-
- #ifdef DF_MACHINE_NEXT
- /*
- #include </usr/include/sys/param.h>
- */
- #endif
-
- const char *ECMessagessArray [MAX_ERROR_KIND + 1] = {
- "Incompatible script version or bad script file",
- "Bad script file or source path",
- "Can't create the directory \"%s\"",
- "Can't create the file \"%s\"",
- "Can't open file %s",
- "HASH ERROR! The file may be corrupted.",
- "Out of memory",
- "You can't merge files or directories with the same name of different types",
- "A non ASCII character was found",
- "Path too long. Shorten paths or eliminate directories",
- "You must specify three or more paths: one root followed by two or more derived to merge into the root",
- "You must specify three paths: one source path, one Difference script path and one destination path",
- "You must specify two paths to compare",
- "Unexpected IO Error on file \"%s\"",
- "Unexpected option on command line: \"%s\""
- };
-
- /* Look at a hunk of edit script and report the range of lines in each file
- that it applies to. HUNK is the start of the hunk, which is a chain
- of `struct change'. The first and last line numbers of file 0 are stored in
- *FIRST0 and *LAST0, and likewise for file 1 in *FIRST1 and *LAST1.
- Note that these are internal line numbers that count from 0.
-
- If no lines from file 0 are deleted, then FIRST0 is LAST0+1.
-
- Also set *DELETES nonzero if any lines of file 0 are deleted
- and set *INSERTS nonzero if any lines of file 1 are inserted.
- If only ignorable lines are inserted or deleted, both are
- set to 0. */
-
- void
- AppendCharToPathName (char *destinationCharPtr, const char theChar)
- {
- int destinationLength;
-
- destinationLength = strlen (destinationCharPtr);
- if (destinationLength + 1 > FILENAME_MAX) {
- fprintf (stderr, "%s%c\n", destinationCharPtr, theChar);
- Error (PATH_TOO_LONG);
- }
- destinationCharPtr += destinationLength;
- *destinationCharPtr++ = theChar;
- *destinationCharPtr = '\0';
- }
-
- void
- AppendStringToPathName (char *destinationCharPtr, const char *suffixCharPtr)
- {
- int destinationLength;
- int suffixLength;
-
- destinationLength = strlen (destinationCharPtr);
- suffixLength = strlen (suffixCharPtr);
- if (destinationLength + suffixLength > FILENAME_MAX) {
- fprintf (stderr, "%s%s\n", destinationCharPtr, suffixCharPtr);
- Error (PATH_TOO_LONG);
- }
- (void) memcpy (destinationCharPtr + destinationLength, suffixCharPtr, suffixLength + 1);
- }
-
- void
- Error (int errorKind)
- {
- ErrorWithStringArgument (errorKind, NULL);
- }
-
- void
- ErrorWithStringArgument (int errorKind, const char *argumentStringPtr)
- {
- if (argumentStringPtr == NULL)
- fprintf (stderr, ECMessagessArray[errorKind], "Null Pointer");
- else
- fprintf (stderr, ECMessagessArray[errorKind], argumentStringPtr);
- fprintf (stderr, ".\n");
- exit (EXIT_FAILURE);
- }
-
- /* Compare two lines.
- Each line is described by a `struct line_def'.
- Return 1 if the lines differ, like `bcmp'. */
-
- int
- line_cmp (struct line_def *s1, struct line_def *s2)
- {
- register char *t1, *t2;
- char savechar;
-
- t1 = s1->text;
- t2 = s2->text;
-
- /* Alter the character following line 2 so it doesn't
- match that following line 1.
- (We used to alter the character after line 1,
- but that caused trouble if line 2 directly follows line 1.) */
- savechar = s2->text[s2->length];
- s2->text[s2->length] = (char) (s1->text[s1->length] + 1);
-
- /* Now find the first mismatch; this won't go past the
- character we just changed. */
- #ifdef DF_COMPILER_MW
- #pragma warn_possunwant off
- #endif
-
- while (*t1++ == *t2++);
-
- #ifdef DF_COMPILER_MW
- #pragma warn_possunwant reset
- #endif
- /* Undo the alteration. */
- s2->text[s2->length] = savechar;
-
- /* If the comparison stopped at the alteration,
- the two lines are identical. */
- if (t2 == s2->text + s2->length + 1)
- return 0;
-
- return (1);
- }
-
- /* Print in a format somewhat like ed commands
- except that each insert command states the number of lines it inserts.
- This format is used for RCS. */
-
- void
- print_rcs_script (struct file_data *file0Ptr, struct file_data *file1Ptr)
- {
- char commandChar;
- register struct change *hunkPtr;
- struct line_def *lastLinePtr;
- struct line_def *linePtr;
- register int numberOfLines;
-
- hunkPtr = file1Ptr->scriptPtr;
- if (hunkPtr == NULL) {
- if (file0Ptr->buffer == NULL) {
- /*
- * File0 doesn't exist so add all of file 1.
- */
- numberOfLines = file1Ptr->buffered_lines;
-
- if (numberOfLines != 0) {
- commandChar = 'a';
- linePtr = file1Ptr->linbuf;
- lastLinePtr = linePtr + numberOfLines - 1;
- if (lastLinePtr->text [lastLinePtr->length - 1] != '\n')
- commandChar = 'A';
- printf ("%c0 %d\n", commandChar, numberOfLines);
- do {
- fwrite (linePtr->text, sizeof (char), linePtr->length, stdout);
- linePtr ++;
- numberOfLines --;
- } while (numberOfLines != 0);
- if (commandChar == 'A')
- putchar ('\n');
- }
- }
- } else
- while (hunkPtr)
- {
- if (hunkPtr->deleted || hunkPtr->inserted) {
-
- /* For deletion, print just the starting line number from file 0
- and the number of lines deleted. */
- if (hunkPtr->deleted)
- printf ("x%d %d\n", hunkPtr->line0 + 1, hunkPtr->deleted);
-
- /* Take last-line-number from file 0 and # lines from file 1. */
- numberOfLines = hunkPtr->inserted;
- if (hunkPtr->inserted != 0)
- {
- commandChar = 'a';
- linePtr = &file1Ptr->linbuf[hunkPtr->line1];
- lastLinePtr = linePtr + numberOfLines - 1;
- if (lastLinePtr->text [lastLinePtr->length - 1] != '\n')
- commandChar = 'A';
-
- printf ("%c%d %d\n", commandChar, hunkPtr->line0 + hunkPtr->deleted, numberOfLines);
-
- /* Print the inserted lines. */
- do {
- fwrite (linePtr->text, sizeof (char), linePtr->length, stdout);
- linePtr ++;
- numberOfLines --;
- } while (numberOfLines != 0);
- if (commandChar == 'A')
- putchar ('\n');
- }
- }
- hunkPtr = hunkPtr->link;
- }
- }
-
- void
- RemoveNameSuffix (char *namePtr)
- {
- char *suffixPtr;
-
- suffixPtr = strrchr (namePtr, DIRECTORY_CHAR);
- if (suffixPtr == NULL)
- suffixPtr = namePtr;
- *suffixPtr = '\0';
- }
-
- /* malloc a block of memory, with fatal error message if we can't do it. */
-
- void *
- xmalloc (size_t size)
- {
- register void *value;
-
- /*
- * MPW realloc returns a memory error when a size of 0 is requested
- */
- if (size == 0)
- size = 1;
- value = malloc (size);
-
- if (value == NULL)
- Error (MEMORY_ERROR);
- return value;
- }
-
- /* realloc a block of memory, with fatal error message if we can't do it. */
-
- void *
- xrealloc (void *old, size_t size)
- {
- register void *value;
-
- /*
- * MPW realloc returns a memory error when a size of 0 is requested
- */
- if (size == 0)
- size = 1;
- value = realloc (old, size);
-
- if (value == NULL)
- Error (MEMORY_ERROR);
- return value;
- }
-
-